package com.yint.http.call;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;

import javax.net.ssl.SSLSocketFactory;

import com.yint.http.Method;
import com.yint.http.ThreadPool;
import com.yint.http.request.Request;
import com.yint.http.response.Response;

public class DefaultCall implements Call
{
	public static ThreadPool threadPool = new ThreadPool();
	private Request request;

	public DefaultCall( Request request )
	{
		this.request = request;
	}

	@Override
	public void enqueue( final CallBack callBack )
	{
		threadPool.addCacheTask(new Runnable()
		{
			
			@Override
			public void run()
			{
				try
				{
					Response response = execute();
					if ( callBack != null )
					{
						callBack.onResponse( DefaultCall.this, response );
					}
				}
				catch ( IOException e )
				{
					if ( callBack != null )
					{
						callBack.onFailure( DefaultCall.this, e );
					}
				}
			}
		});
	}

	@Override
	public Response execute() throws IOException
	{
		if ( request == null )
		{
			throw new IOException( "request is null" );
		}
		return new Response( request( request ) );
	}

	private HttpURLConnection request( Request request ) throws IOException
	{
		HttpURLConnection conn = getConnect( request );

		if ( Method.POST == request.getMethod() && request.getBody() != null )
		{
			request.getBody().toStream( conn.getOutputStream() );
		}
		conn.connect();
		return conn;
	}

	private HttpURLConnection getConnect( Request request ) throws IOException
	{
		HttpURLConnection conn = onGetConnect( request.getSSLSocketFactory(), request.getUrlStr() );
		if ( request.getConnectTimeout() > 0 )
		{
			conn.setConnectTimeout( request.getConnectTimeout() );
		}
		if ( request.getReadTimeout() > 0 )
		{
			conn.setReadTimeout( request.getReadTimeout() );
		}
		setHead( conn, request.getMethod(), request.getHeads() );
		return conn;
	}

	protected HttpURLConnection onGetConnect( SSLSocketFactory factory, String urlStr )throws IOException
	{
		return ( HttpURLConnection ) new URL( urlStr ).openConnection();
	}

	private void setHead( HttpURLConnection conn, Method method, Map< String, String > heads )throws IOException
	{
		conn.setRequestMethod( method.getValue() );
		if ( Method.POST == method )
		{
			conn.setDoInput( true );
			conn.setDoOutput( true );
			conn.setUseCaches( false );
		}
		conn.setRequestProperty( "Connection", "Keep-Alive" );
		conn.setRequestProperty( "Charset", "UTF-8" );
		onSetHeads( conn, heads );
	}

	/**
	 * 设置传递过来的 http头信息
	 * 
	 * @param conn
	 * @param heads
	 *            http请求头信息 键值对类型
	 */
	protected void onSetHeads( HttpURLConnection conn, Map< String, String > heads )
	{
		if ( conn != null && heads != null && heads.size() > 0 )
		{
			Iterator< Map.Entry< String, String > > iterator = heads.entrySet().iterator();
			while ( iterator.hasNext() )
			{
				Map.Entry< String, String > entry = iterator.next();
				conn.setRequestProperty( entry.getKey(), entry.getValue() );
			}
		}
	}

}
